package cn.ronghuanet.gift.service.impl;

import cn.ronghuanet.gift.client.LoginUserClient;
import cn.ronghuanet.gift.domain.Employee;
import cn.ronghuanet.gift.domain.LoginUser;
import cn.ronghuanet.gift.domain.Tenant;
import cn.ronghuanet.gift.domain.TenantType;
import cn.ronghuanet.gift.dto.TenantSettlementDto;
import cn.ronghuanet.gift.exception.BusinessException;
import cn.ronghuanet.gift.exception.GiftAssert;
import cn.ronghuanet.gift.exception.code.ErrorCode;
import cn.ronghuanet.gift.mapper.EmployeeMapper;
import cn.ronghuanet.gift.mapper.TenantMapper;
import cn.ronghuanet.gift.query.TenantQuery;
import cn.ronghuanet.gift.service.ITenantService;
import cn.ronghuanet.gift.util.AjaxResult;
import cn.ronghuanet.gift.util.PageList;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author ysosang
 * @since 2022-12-06
 */
@Service
public class TenantServiceImpl extends ServiceImpl<TenantMapper, Tenant> implements ITenantService {

    @Autowired
    private TenantMapper tenantMapper;

    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private LoginUserClient loginUserClient;
    @Override
    public PageList<Tenant> selectPageList(TenantQuery query) {
        //分页条件,只要你往tenantMapper传入Page对象,mybatisplus会自动做分页,并且把满足条件的总数放到page对象total属性中
        Page<TenantType> page = new Page<>(query.getPage(),query.getRows());

        //做分页查询,并且返回当前页数据
        List<Tenant>  rows = tenantMapper.selectPageList(page,query);

        //封装自己PageList
        return new PageList<>(page.getTotal(),rows);
    }

    @Override
    //@Transactional
    @GlobalTransactional
    public AjaxResult settlement(TenantSettlementDto tenantSettlementDto) {

        //1 校验
        validate(tenantSettlementDto);
        Employee admin = tenantSettlementDto.getAdmin();
        Tenant tenant = tenantSettlementDto.getTenant();
        Long mealId = tenantSettlementDto.getMealId();

        //2 @TODO 百度的人工智能审核,提示错误!如果成功,还要加审核日志!      !~把数据先保存到数据库,传id到前提,前台通过id做回显

        //3 远程调用授权中心接口,获取loginId
        LoginUser loginUser = new LoginUser();
        BeanUtils.copyProperties(admin, loginUser);
        loginUser.setType(0);
        AjaxResult ajaxResult = loginUserClient.addOrUpdate(loginUser);
        if (!ajaxResult.isSuccess())
            return ajaxResult;

        Long loginId = Long.valueOf(ajaxResult.getResultObj().toString()); //这儿有bug

        //4 保存管理员
        admin.setLoginId(loginId);
        employeeMapper.insert(admin);

        //5 保存租户:管理套餐
        tenant.setAdminId(admin.getId());
        tenantMapper.insert(tenant);

        Map<String,Object> params = new HashMap<>();
        params.put("tenantId", tenant.getId());
        params.put("mealId", mealId);
        params.put("expireDate", DateUtils
                .addYears(new Date(), 1));
        params.put("state", 0);
        tenantMapper.saveTenantMeals(params);
        //6 @TODO 发送激活管理员邮件


        //7: @TODO 在激活的那地方,实现发送消息(邮件或者短信),已经入住成功!可以正常登陆使用了
        return AjaxResult.me();
    }

    private void validate(TenantSettlementDto tenantSettlementDto){

        //1参数校验
        //1.1 空校验 isNotBlank("   "为false,底层判断每一个字符是否是空) isNotEmpty("   "都为true)
        /*GiftAssert.assertNotNull(tenantSettlementDto);
        Employee admin = tenantSettlementDto.getAdmin();
        GiftAssert.assertNotNull(admin);
        Tenant tenant = tenantSettlementDto.getTenant();
        GiftAssert.assertNotNull(tenant);
        Long mealId = tenantSettlementDto.getMealId();
        GiftAssert.assertNotNull(mealId);*/
        Employee admin = tenantSettlementDto.getAdmin();
        Tenant tenant = tenantSettlementDto.getTenant();

        //1.2 两次密码不相同
        //GiftAssert.assertStrEq(admin.getPassword(),admin.getComfirmPassword(),"两次密码不相同!");
        GiftAssert.assertStrEq(admin.getPassword(),admin.getComfirmPassword(),
                ErrorCode.ERROR_CODE_TENNAT_PASSWORD_NOTEQ);

        //1.3 租户已经存在
        Wrapper<Tenant> wrapper = new EntityWrapper<>();
        wrapper.eq("company_name", tenant.getCompanyName());  //companyName=XXX
        List<Tenant> tenants = tenantMapper.selectList(wrapper);
        GiftAssert.assertListNull(tenants,ErrorCode.ERROR_CODE_TENNAT_EXIST);


        //1.4 管理员校验   方案1:管理员已经存在!不能注册租户,直接登录后再后台添加!
        List<Employee> employees = employeeMapper.selectList(new EntityWrapper<Employee>().
                eq("username", admin.getUsername()));
        GiftAssert.assertListNull(tenants,ErrorCode.ERROR_CODE_TENNAT_ADMIN_EXIST);
    }

    //自定义异常
    private void validate2(TenantSettlementDto tenantSettlementDto){

        //1参数校验
        //1.1 空校验 isNotBlank("   "为false,底层判断每一个字符是否是空) isNotEmpty("   "都为true)
        if (Objects.isNull(tenantSettlementDto))
            throw new RuntimeException("非法请求!请输入相关信息后再操作!");
        Employee admin = tenantSettlementDto.getAdmin();
        if (Objects.isNull(admin))
            throw new RuntimeException("非法请求!请输入相关信息后再操作!");
        Tenant tenant = tenantSettlementDto.getTenant();
        if (Objects.isNull(tenant))
            throw new RuntimeException("非法请求!请输入相关信息后再操作!");
        //1.2 两次密码不相同

        if (!admin.getPassword().equals(admin.getComfirmPassword()))
            throw new BusinessException("两次密码不相同!");
        //1.3 租户已经存在
        Wrapper<Tenant> wrapper = new EntityWrapper<>();
        wrapper.eq("company_name", tenant.getCompanyName());  //companyName=XXX
        List<Tenant> tenants = tenantMapper.selectList(wrapper);
        if (tenants!=null && tenants.size()>0)
            throw new BusinessException("该租户已经入住!请直接登录使用");
        //1.4 管理员校验   方案1:管理员已经存在!不能注册租户,直接登录后再后台添加!
        List<Employee> employees = employeeMapper.selectList(new EntityWrapper<Employee>().
                eq("username", admin.getUsername()));
        if (employees!=null && employees.size()>0)
            throw new BusinessException("已经入住过店铺!请直接登录后添加新的店铺!");
    }

    //原始版本
    private void validate1(TenantSettlementDto tenantSettlementDto){

        //1参数校验
        //1.1 空校验 isNotBlank("   "为false,底层判断每一个字符是否是空) isNotEmpty("   "都为true)
        if (Objects.isNull(tenantSettlementDto))
            throw new RuntimeException("非法请求!请输入相关信息后再操作!");
        Employee admin = tenantSettlementDto.getAdmin();
        Tenant tenant = tenantSettlementDto.getTenant();
        Long mealId = tenantSettlementDto.getMealId();
        //1.2 两次密码不相同

        if (!admin.getPassword().equals(admin.getComfirmPassword()))
            throw new RuntimeException("两次密码不相同!");
        //1.3 租户已经存在
        Wrapper<Tenant> wrapper = new EntityWrapper<>();
        wrapper.eq("company_name", tenant.getCompanyName());  //companyName=XXX
        List<Tenant> tenants = tenantMapper.selectList(wrapper);
        if (tenants!=null && tenants.size()>0)
            throw new RuntimeException("该租户已经入住!请直接登录使用");
        //1.4 管理员校验   方案1:管理员已经存在!不能注册租户,直接登录后再后台添加!
        List<Employee> employees = employeeMapper.selectList(new EntityWrapper<Employee>().
                eq("username", admin.getUsername()));
        if (employees!=null && employees.size()>0)
            throw new RuntimeException("已经入住过店铺!请直接登录后添加新的店铺!");
    }

}
